package com.zzzy.cont.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuozhengsoft.pageoffice.OpenModeType;
import com.zzzy.common.util.*;
import com.zzzy.cont.common.enums.ConFileHistoryEditionEnum;
import com.zzzy.cont.common.enums.ConStatusEnum;
import com.zzzy.framework.common.util.PageOfficeUtil;
import com.zzzy.cont.dao.entity.ConFile;
import com.zzzy.cont.dao.entity.ConFileHistory;
import com.zzzy.cont.dao.entity.Contract;
import com.zzzy.cont.dao.mapper.ConFileHistoryMapper;
import com.zzzy.cont.service.mycon.MyConService;
import com.zzzy.cont.vo.contract.my.ConFileHistoryRes;
import com.zzzy.cont.vo.pageoffice.OpenOfficeFileRes;
import com.zzzy.framework.common.util.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 合同文件历史版本表 服务实现类
 *
 * @author fc
 * @since 2024-06-04
 */
@Service
public class ConFileHistoryService extends ServiceImpl<ConFileHistoryMapper, ConFileHistory> {

    @Resource
    private ConFileService conFileService;
    @Resource
    private MyConService myConService;
    @Resource
    private ConActivityNoteService conActivityNoteService;

    /**
     * 添加初始版本备份
     */
    public void addInitHistory(Long conId) {
        ConFile conFile = conFileService.getConFileByConId(conId);
        ConFileHistory conFileHistory = new ConFileHistory();
        conFileHistory.setConId(conFile.getConId());
        conFileHistory.setEdition(ConFileHistoryEditionEnum.INITIAL.getValue());
        conFileHistory.setFileBlob(Objects.nonNull(conFile.getWordFileBlob()) ? conFile.getWordFileBlob() : conFile.getPdfFileBlob());
        conFileHistory.setCreateTime(LocalDateTime.now());
        baseMapper.insert(conFileHistory);
    }

    public void clearHistoryByConId(Long conId) {
        baseMapper.delete(new LambdaQueryWrapper<ConFileHistory>().eq(ConFileHistory::getConId, conId));
    }
    /**
     * 添加审核完毕版本备份
     */
    public void addAuditedHistory(Long conId) {
        ConFile conFile = conFileService.getConFileByConId(conId);
        ConFileHistory conFileHistory = new ConFileHistory();
        conFileHistory.setConId(conFile.getConId());
        conFileHistory.setEdition(ConFileHistoryEditionEnum.AUDITED.getValue());
        conFileHistory.setFileBlob(conFile.getWordFileBlob());
        conFileHistory.setCreateTime(LocalDateTime.now());
        baseMapper.insert(conFileHistory);
    }

    /**
     * 添加签订完毕版本备份
     */
    public void addSignedHistory(Long conId) {
        ConFile conFile = conFileService.getConFileByConId(conId);
        ConFileHistory conFileHistory = new ConFileHistory();
        conFileHistory.setConId(conFile.getConId());
        conFileHistory.setEdition(ConFileHistoryEditionEnum.SIGNED.getValue());
        conFileHistory.setFileBlob(conFile.getPdfFileBlob());
        conFileHistory.setCreateTime(LocalDateTime.now());
        baseMapper.insert(conFileHistory);
    }

    /**
     * 添加签订中备份版本备份
     */
    public void addSigningHistory(Long conId) {
        ConFile conFile = conFileService.getConFileByConId(conId);
        ConFileHistory conFileHistory = new ConFileHistory();
        conFileHistory.setConId(conFile.getConId());
        conFileHistory.setEdition(ConFileHistoryEditionEnum.SIGNING.getValue());
        conFileHistory.setFileBlob(conFile.getPdfFileBlob());
        conFileHistory.setCreateTime(LocalDateTime.now());
        baseMapper.insert(conFileHistory);
    }
    public List<ConFileHistoryRes> getConHistoryFileList(Long conId) {
        Contract contract = myConService.getConByIdForQuery(conId);
        LambdaQueryWrapper<ConFileHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(ConFileHistory::getId, ConFileHistory::getEdition, ConFileHistory::getCreateTime);

        wrapper.eq(ConFileHistory::getConId, conId);
        List<ConFileHistory> conFileHistoryList = baseMapper.selectList(wrapper);
        List<ConFileHistoryRes> conFileHistoryResList = new ArrayList<>();
        boolean isSigning = ConStatusEnum.SIGN.getValue().equals(contract.getStatus());
        Long userId = SecurityUtils.getLoginUser().getId();
        for (ConFileHistory conFileHistory : conFileHistoryList) {
            ConFileHistoryRes historyRes = CglibBeanCopierUtil.copy(conFileHistory, ConFileHistoryRes.class);
            if (isSigning && userId.equals(contract.getOperatorId()) && userId.equals(contract.getUserId())
                    && ConFileHistoryEditionEnum.SIGNING.getValue().equals(conFileHistory.getEdition())){
                historyRes.setRestoreButton(true);
            }
            conFileHistoryResList.add(historyRes);
        }
        return conFileHistoryResList;
    }

    public OpenOfficeFileRes getPageOfficeResByConId(Long id, String openFileUrl) {
        ConFileHistory conFileHistory = getConFileHistoryById(id);

        if (FileUtil.checkIsWord(conFileHistory.getFileBlob())){
            String pdfFileName = conFileHistory.getEdition() + "." + FileUtil.getFileType(conFileHistory.getFileBlob());
            String wordHtml = PageOfficeUtil.getWordHtml(openFileUrl, pdfFileName, OpenModeType.docReadOnly);
            return OpenOfficeFileRes.builder().html(wordHtml).build();
        } else {
            String wordFileName = conFileHistory.getEdition() + "." + FileUtil.PDF;
            String pdfHtml = PageOfficeUtil.getPdfHtml(openFileUrl, wordFileName);
            return OpenOfficeFileRes.builder().html(pdfHtml).pdf(true).build();
        }
    }

    public ConFileHistory getConFileHistoryById(Long id) {
        ConFileHistory conFileHistory = baseMapper.selectById(id);
        AssertUtil.nonNull(conFileHistory, "合同历史文件不存在");
        myConService.validateAuthForQuery(conFileHistory.getConId());
        return conFileHistory;
    }

    public ConFileHistory getConFileHistoryByConIdAndEdition(Long conId, ConFileHistoryEditionEnum editionEnum) {
        return baseMapper.selectOne(new LambdaQueryWrapper<ConFileHistory>().eq(ConFileHistory::getConId, conId).eq(ConFileHistory::getEdition, editionEnum.getValue()));
    }

    public void deleteByConId(Long conId) {
        clearHistoryByConId(conId);
    }

    /**
     * 恢复历史版本
     */
    @Transactional
    public void restoreConToHistory(Long id) {
        ConFileHistory conFileHistory = getConFileHistoryById(id);
        Contract contract = myConService.getConByIdForUpdate(conFileHistory.getConId());
        AssertUtil.isEquals(ConStatusEnum.SIGN.getValue(), contract.getStatus(), "只有签订中合同可以恢复历史版本");
        AssertUtil.isEquals(ConFileHistoryEditionEnum.SIGNING.getValue(), conFileHistory.getEdition(), "只能恢复到签订中备份版本");

        myConService.updatePdf(conFileHistory.getConId(), conFileHistory.getFileBlob(), false);
        String message = "将合同正文还原到 ["+ LocalDateUtils.getDefaultDateStr(conFileHistory.getCreateTime()) +"] 的签订中备份版本";
        conActivityNoteService.addSysNote(conFileHistory.getConId(), message);
    }
}
